#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#define High 20  //游戏画面尺寸
#define Width 50

// 全局变量
int moveDirection;    //小蛇移动方向，1，2，3，4分别表示上下左右
int canvas[High][Width] = { 0 };  //二维数组记录游戏中对应的元素
					   //0输出空格，-1输出边框#,1输出蛇头@，>1为蛇身*

void HideCursor()
{
	CONSOLE_CURSOR_INFO cursor_info = { 1,0 };
	SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void gotoxy(int x, int y)
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle, pos);
}

void startup() // 数据初始化
{
	int i, j;
	//以下设定边框的数值
	for (i = 0; i < High; i++)
	{
		canvas[i][0] = -1;
		canvas[i][Width - 2] = -1;
	}
	for (j = 0; j < Width; j++)
	{
		canvas[0][j] = -1;
		canvas[High - 2][j] = -1;
	}

	//以下设定蛇头蛇身
	canvas[High / 2][Width / 2] = 1;

	for (i = 1; i <= 4; i++)
	{
		canvas[High / 2][Width / 2 - i] = i + 1;
	}

	moveDirection = 4;
}

void moveSnakeByDirection()
{
	int i, j;
	int max = 0;
	int oldTail_i, oldTail_j;   //记录旧的蛇尾
	int oldHead_i, oldHead_j;   //记录旧的蛇头

	for (i = 1; i < High - 2; i++)
	{
		for (j = 1; j < Width - 2; j++)
		{
			if (canvas[i][j] > 0)
			{
				//对所有大于0的元素＋1
				canvas[i][j]++;

				//求出最大值max
				if (max < canvas[i][j])
				{
					max = canvas[i][j];
					oldTail_i = i;
					oldTail_j = j;
				}

				//记录旧蛇头位置
				if (canvas[i][j] == 2)
				{
					oldHead_i = i;
					oldHead_j = j;
				}
			}
		}
	}

	canvas[oldTail_i][oldTail_j] = 0;  //最大值所在元素变为0

	if (moveDirection == 1)  //向上
		canvas[oldHead_i - 1][oldHead_j] = 1;
	if (moveDirection == 2)  //向下
		canvas[oldHead_i + 1][oldHead_j] = 1;
	if (moveDirection == 3)  //向左
		canvas[oldHead_i][oldHead_j - 1] = 1;
	if (moveDirection == 4)  //向右
		canvas[oldHead_i][oldHead_j + 1] = 1;
}


void show()  // 显示画面
{
	gotoxy(0, 0);  // 光标移动到原点位置进行重画清屏
	int i, j;
	for (i = 0; i < High - 1; i++)
	{
		for (j = 0; j < Width - 1; j++)
		{
			if (canvas[i][j] == 0)
				printf(" ");  //   输出空格
			else if (canvas[i][j] == -1)
				printf("#");   //输出边界#
			else if (canvas[i][j] == 1)
				printf("@");   //输出蛇头@
			else if (canvas[i][j] > 1)
				printf("*");   //输出蛇身*
		}
		printf("\n");
	}
	Sleep(150);
	HideCursor();
}

void updateWithoutInput()  // 与用户输入无关的更新
{
	moveSnakeByDirection();
}

void updateWithInput()  // 与用户输入有关的更新
{
	char input;
	if (kbhit())  //判断是否有输入
	{
		input = getch();

		if (input == 'A')
			moveDirection = 3;
		if (input == 'D')
			moveDirection = 4;
		if (input == 'W')
			moveDirection = 1;
		if (input == 'S')
			moveDirection = 2;
	}
}

void main()
{
	startup();  // 数据初始化	
	while (1) //  游戏循环执行
	{
		show();  // 显示画面
		updateWithoutInput();  // 与用户输入无关的更新
		updateWithInput();  // 与用户输入有关的更新
	}
	system("pause");
}